﻿/*
 * Author: Kasper van Voorst
 * Modified by Martijn Koopman to support specified directions
 * 
 * Description: A dilation filter used to connect lines or small clusters of pixels together by expanding them.
 * */

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;

namespace LibraryCS {
    public class DilationFilter : VisionAlgorithm {

        // The amount of pixels a foreground pixel should be dialted:
        private int horizontalDilateSize;   // horizontal
        private int verticalDilateSize;     // vertical

        byte[] grayValues;
        public DilationFilter(String name)
            : base(name) {
        }

        public override System.Drawing.Bitmap DoAlgorithm(Bitmap sourceImage) {

            VImage sourceim = new VImage(sourceImage);
            grayValues = sourceim.GrayPixels;

            int horizontalRadius = horizontalDilateSize / 2;
            int verticalRadius = verticalDilateSize / 2;

            byte highestGrayvalue = 0;

            byte[] outputimage = new byte[sourceim.Height * sourceim.Width];

            for (int y = verticalRadius; y < sourceImage.Height - verticalRadius; y++) {

                for (int x = horizontalRadius; x < sourceImage.Width - horizontalRadius; x++) {

                    highestGrayvalue = 0;

                    //check the kernel for the highest gray value
                    for (int kery = y - verticalRadius; kery <= y + verticalRadius; kery++) {

                        for (int kerx = x - horizontalRadius; kerx <= x + horizontalRadius; kerx++) {
                            if (grayValues[(kery * sourceim.Width) + kerx] > highestGrayvalue) {
                                highestGrayvalue = grayValues[(kery * sourceim.Width) + kerx];
                            }
                        }
                    }

                    //apply new highest grayvalue
                    outputimage[(y * sourceim.Width) + x] = highestGrayvalue;
                }
            }
            return sourceim.returnNewBitmapOutput(outputimage);
        }


        #region GUI Functions

        public override List<System.Windows.Forms.Control> createControls() {
            List<Control> Controls = new List<Control>();

            // Horizontal dilation
            // Label
            Label horizontalDilationLb = new Label();
            horizontalDilationLb.AutoSize = true;
            horizontalDilationLb.Text = "Horizontal:";
            horizontalDilationLb.Name = "lbHorizontalDilation";

            // TextBox
            TextBox horizontalDilationTb = new TextBox();
            horizontalDilationTb.Name = "tbHorizontalDilation";
            horizontalDilationTb.AcceptsReturn = false;
            horizontalDilationTb.MaxLength = 3;
            horizontalDilationTb.Multiline = false;
            horizontalDilationTb.Size = new Size(50, 25);
            horizontalDilationTb.Text = "10";

            // Horizontal dilation
            // Label
            Label verticalDilationLb = new Label();
            verticalDilationLb.AutoSize = true;
            verticalDilationLb.Text = "Vertical:";
            verticalDilationLb.Name = "lbVerticalDilation";

            // TextBox
            TextBox verticalDilationTb = new TextBox();
            verticalDilationTb.Name = "tbVerticalDilation";
            verticalDilationTb.AcceptsReturn = false;
            verticalDilationTb.MaxLength = 3;
            verticalDilationTb.Multiline = false;
            verticalDilationTb.Size = new Size(50, 25);
            verticalDilationTb.Text = "10";

            // Add the controls to the list
            Controls.Add(horizontalDilationTb);
            Controls.Add(horizontalDilationLb);
            Controls.Add(verticalDilationTb);
            Controls.Add(verticalDilationLb);

            // Return the list
            return Controls;
        }

        public override void setSettings(List<object> settings) {
            horizontalDilateSize = Int32.Parse(((TextBox)settings[0]).Text);
            verticalDilateSize = Int32.Parse(((TextBox)settings[1]).Text);

            Debug.WriteLine("Dilation:");
            Debug.WriteLine("Horizontal: " + horizontalDilateSize);
            Debug.WriteLine("Vertical: " + verticalDilateSize);
        }

        #endregion
    }
}
